package com.basic.gateway.filter;

import com.basic.gateway.constants.KeyName;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.cloud.gateway.filter.GatewayFilter;
import org.springframework.cloud.gateway.filter.factory.AbstractGatewayFilterFactory;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpStatus;
import org.springframework.http.server.reactive.ServerHttpRequest;
import org.springframework.http.server.reactive.ServerHttpResponse;
import org.springframework.stereotype.Component;
import org.springframework.util.StringUtils;

import java.util.Arrays;
import java.util.List;

/**
 * Description: Token 校验 的 FilterFactory.<br>
 *
 * @author m-xy
 *     Created By 2018/12/14 上午11:51
 */
@Component
public class AuthorizeGatewayFilterFactory extends AbstractGatewayFilterFactory<AuthorizeGatewayFilterFactory.Config> {

    /**
     * 日志.
     */
    private static final Logger LOGGER = LoggerFactory.getLogger(AuthorizeGatewayFilterFactory.class);


    public AuthorizeGatewayFilterFactory() {
        super(Config.class);
        LOGGER.info("Loaded GatewayFilterFactory [Authorize]");
    }

    @Override
    public List<String> shortcutFieldOrder() {
        return Arrays.asList("enabled");
    }

    @Override
    public GatewayFilter apply(AuthorizeGatewayFilterFactory.Config config) {
        return (exchange, chain) -> {
            ServerHttpRequest request = exchange.getRequest();
            HttpHeaders headers = request.getHeaders();
            String token = headers.getFirst(KeyName.AUTHORIZE_TOKEN);
            String uid = headers.getFirst(KeyName.AUTHORIZE_UID);
            if (token == null) {
                token = request.getQueryParams().getFirst(KeyName.AUTHORIZE_TOKEN);
            }
            if (uid == null) {
                uid = request.getQueryParams().getFirst(KeyName.AUTHORIZE_UID);
            }
            ServerHttpResponse response = exchange.getResponse();
            if (StringUtils.isEmpty(token)) {
                LOGGER.info("[请求中不存在 Authorization 信息]");
                response.setStatusCode(HttpStatus.UNAUTHORIZED);
                return response.setComplete();
            }
            if (token.startsWith(KeyName.BEARER)) {
                response.setStatusCode(HttpStatus.UNAUTHORIZED);
                return response.setComplete();
            }
            return chain.filter(exchange);
        };
    }

    /**
     * 配置是否开启认证.
     */
    public static class Config {
        /**
         * 控制是否开启认证.
         */
        private boolean enabled;

        public Config() {
        }

        public boolean isEnabled() {
            return enabled;
        }

        public void setEnabled(boolean enabled) {
            this.enabled = enabled;
        }
    }
}
